"use strict";
// 引入脚手架生成器 - https://www.npmjs.com/package/yeoman-generator
const Generator = require("yeoman-generator");
// 引入 chalk 文字输出颜色样式库 - https://www.npmjs.com/package/chalk
const chalk = require("chalk");
// 引入 Yeoman 文字输出样式库
const yosay = require("yosay");
// 引入 cowsay 文字输出样式库
const cowsay = require("cowsay");
// 定义密码常量
const PASSWORD = "DefChiggaVue";

// 自定义生成器
module.exports = class extends Generator {
  /* 提示 */
  prompting() {
    // Yeoman 图案文字输出
    this.log(
      yosay(
        `
        欢迎来到七哥的超级 ${chalk.blue("generator-def-chigga-vue")} 生成器!
        如有任何问题请联系 ${chalk.blue("defchigga@qq.com")}
        `
      )
    );
    // 定义提示类型 - https://www.npmjs.com/package/inquirer#separator
    const prompts = [
      {
        type: "confirm", // 交互类型确认
        name: "ready", // 自定义字段名
        message: "准备好一起冒险了吗？", // 引导词
        default: true // 默认值
      },
      {
        type: "confirm",
        name: "git",
        message: "当前是否为git环境？",
        // Default为函数时可以对之前接收值做处理
        default: function(value) {
          // Value为之前步骤回答的参数对象
          // 将函数声明为异步，并保存完成的回调
          const done = this.async();
          // 做异步的东西
          setTimeout(function() {
            // 如果不是git环境
            if (!value.ready) {
              // 在 done 回调中传递返回值
              done(chalk.red("滚！"));
              return;
            }

            // 在 done 回调中传递返回值
            done(null, true);
          }, 500);
        }
      },
      {
        type: "password",
        name: "password",
        message: "请输入访问密码",
        // Default为函数时可以对之前接收值做处理
        default: function(value) {
          // Value为之前步骤回答的参数对象
          // 将函数声明为异步，并保存完成的回调
          const done = this.async();
          // 做异步的东西
          setTimeout(function() {
            // 如果不是git环境
            if (!value.git) {
              // 在 done 回调中传递返回值
              done(chalk.red("请先初始化git环境!"));
              return;
            }

            // 在 done 回调中传递返回值
            done(null, true);
          }, 500);
        },
        // 输入数据校验 传统方式：使用 this.async
        validate: function(value) {
          // 将函数声明为异步，并保存完成的回调
          const done = this.async();
          // 做异步的东西
          setTimeout(function() {
            if (value !== PASSWORD) {
              // 在 done 回调中传递返回值
              done("密码不正确, 请重新输入");
              return;
            }

            // 在 done 回调中传递返回值
            done(null, true);
          }, 2000);
        }
      },
      {
        type: "input",
        name: "name",
        message: "请输入项目名称",
        default: this.appname // 项目目录名称
      },
      {
        type: "list",
        name: "type",
        message: "请选择项目模版",
        choices: ["vue3-ts-vite-init", "vue3-ts-cli-init", "vue3-ts-cli-admin"]
      },
      {
        type: "list",
        name: "install",
        message: "请选择包管理器",
        choices: ["yarn", "npm", "bower"]
      }
    ];
    // 终端提示 - 底层使用 Inquirer.js 库 https://www.npmjs.com/package/inquirer
    return this.prompt(prompts)
      .then(answers => {
        this.answers = answers;
      })
      .catch(error => {
        throw Error(error);
      });
  }

  /* 写入 */
  writing() {
    // 文件拷贝
    // Eg. this.fa.copy // 模版语法 ejs 不会替换变量
    this.fs.copyTpl(
      // 需要拷贝文件所在路径
      this.templatePath(`${this.answers.type}/(.**|**)`),
      // 需拷贝目的地所在路径
      this.destinationPath("./"),
      // Esj模版传参
      this.answers
    );
  }

  /* 写入完成后执行项目依赖安装 - https://yeoman.github.io/generator/actions_install.html */
  install() {
    // 处理依赖安装方式
    let pm = this.answers.install;
    let installObj = {
      yarn: false,
      npm: false,
      bower: false
    };
    installObj[pm] = true;
    this.installDependencies(installObj);
    // Yeoman 图案文字输出
    let cmd = pm === "yarn" ? "yarn serve" : `${pm} run serve`;
    this.log(
      cowsay.say({
        text: `
        ${chalk.greenBright("请耐心等待依赖安装...")}
        安装完成之后~
        输入 ${chalk.green(cmd)} 命令
        即可开始搬砖~
        `
      })
    );
  }
};
